#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <linux/input.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/soundcard.h>
#include <dirent.h>

int ts_x, ts_y;
int flag_x = 0, flag_y = 0, flag_x_y = 0;
int first_press_flag = 0;
int up_down_slide_flag = 0;
int slider_down = 0;
int slider_up = 0;
int old_y = 400;
struct input_event ts;
int read_pipe_fd, write_pipe_fd;
DIR *audio_dir = NULL;
struct dirent* audio_dirent;
int next_song_flag = 0;
int current_song = 1;
char *audio_name[2];
int next_song_fd[2];
int play_pause_flag = 1;
int music_start_play = 1;
int mute_flag = 1;

pthread_t music_slide_tid;
pthread_t music_area_switch_tid;
pthread_t music_screen_switch_tid;

pthread_mutex_t music_mutex;
pthread_cond_t music_cond;

pthread_mutex_t screen_mutex;
pthread_cond_t screen_cond;

pthread_mutex_t slide_mutex;
pthread_cond_t slide_cond;

int like_flag = 0;

int screen_change = 0;
//int slide_change = 0;

/**
 *lcd屏显示bmp格式图片函数
 *@param     pathname    图片名字
 *@param     x0          图片在LCD上显示的x起点坐标
 *@param     y0          图片在LCD上显示的y起点坐标
 *@return    函数返回值
 */
int lcd_show_bmp(char *pathname, int x0, int y0)
{
	//1、打开设备文件
	int lcd = open("/dev/fb0", O_RDWR);
	if(-1 == lcd)
	{
		printf("lcd open error!\n");
		return -2;
	}
	
	//2、内存映射
	char *ptr =  (char *)mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, 
	                MAP_SHARED, lcd, 0);
	if(NULL == ptr)
	{
		printf("mmap error!\n");
		return -3;
	}
	//清除背景色
	//bzero(ptr, 800*480*4);
	
	//打开图片
	int bmp = open(pathname, O_RDWR);
	if(-1 == bmp)
	{
		printf("bmp open error!\n");
		return -2;
	}
	
	//读取图片相关信息
	int bmp_size, bmp_width, bmp_height;
	//大小
	lseek(bmp, 2, SEEK_SET);
	read(bmp, &bmp_size, sizeof(bmp_size));
	
	//宽度和高度
	lseek(bmp, 18, SEEK_SET);
	read(bmp, &bmp_width, sizeof(bmp_width));
	read(bmp, &bmp_height, sizeof(bmp_height));
	
	//读取图片的颜色数据
	lseek(bmp, 54, SEEK_SET);
	char *bmp_buf = malloc(bmp_size);	//申请空间
	read(bmp, bmp_buf, bmp_width*bmp_height*3);
 
	
	//对颜色数据进行处理（上下颠倒以及数据混乱）
	int bmp_sum = 0;
	int lcd_sum = 0;
	for(int y=0; y+y0<480 && y<bmp_height; y++)
	{
		for(int x=0; x+x0<800 && x<bmp_width; x++)
		{
			bmp_sum = 3*(x+((bmp_height-1-y)*bmp_width));
			lcd_sum = 4*(800*(y+y0)+x+x0);
			
			//等号的坐标属于lcd屏幕， 等号的右边是bmp图像数据
			ptr[lcd_sum+0] = bmp_buf[bmp_sum+0]; //蓝色数据
			ptr[lcd_sum+1] = bmp_buf[bmp_sum+1]; //绿色数据
			ptr[lcd_sum+2] = bmp_buf[bmp_sum+2]; //红色数据
			ptr[lcd_sum+3] = bmp_buf[bmp_sum+3]; //透明度数据
		}
		//usleep(1);
	}
    //释放相关资源
	munmap(ptr, 800*480*4);
	free(bmp_buf);
	//3、关闭文件
	close(lcd);
	close(bmp);
}


void music_get_touch()
{
    //1、打开设备文件
    int touch_fd = open("/dev/input/event0", O_RDONLY);
    if(-1 == touch_fd)
    {
        printf("event0 open error!\n");
    }

    while(1)
    {
        read(touch_fd, &ts, sizeof(ts));
	//3、分析数据
        if(EV_ABS == ts.type) //判断是否为触摸屏事件
        {
            if(ABS_X == ts.code)//判断是否为x轴数据
            {
                ts_x = ts.value;
                flag_x = 1;	
            }
            else if(ABS_Y == ts.code) //判断是否为y轴数据
            {
                ts_y = ts.value;
                flag_y = 1;
            }
	}
	if(EV_KEY == ts.type){
		//刚触碰的坐标/长按时
		if(ts.code == BTN_TOUCH && ts.value == 1)
		{
			old_y = ts_y;
			first_press_flag = 1;
		}
	}

	if(EV_KEY == ts.type){
		if(ts.code == BTN_TOUCH && ts.value == 0){
			
			if(((ts_y > old_y) && (ts_y - old_y > 150)))
			{
				printf("old_y = %d, ts_y = %d\r\n");
				up_down_slide_flag = 1;
				slider_down = 1;			
				old_y = 400;

			}	
		
			else if(((old_y > ts_y) && (old_y - ts_y > 150)))
			{
				printf("old_y = %d, ts_y = %d\r\n");
				up_down_slide_flag = 1;
				slider_up = 1;
				old_y = 400;
			}
		}
	}
	if(flag_x == 1 && flag_y == 1 && first_press_flag == 1){ 
		flag_x = 0;
		flag_y = 0;
		//pthread_mutex_lock(&music_mutex);
		flag_x_y = 1;  
		//pthread_mutex_unlock(&music_mutex);
		//pthread_cond_signal(&music_cond);
		//黑色底板才需要执行如下操作
		ts_x = ts_x*800/1024;
		ts_y = ts_y*480/600; 

		//break;                    
        }
    }
    close(touch_fd);
}

void *music_area_switch(void *arg)
{
	printf("enter music_area_switch\r\n");
	while(1){
		//pthread_mutex_lock(&music_mutex);
		//while(flag_x_y == 0)
			//pthread_cond_wait(&music_cond, &music_mutex);
		while(flag_x_y == 1){
			if((ts_y > 400 && ts_y < 450) && (ts_x > 70 && ts_x < 110))
			{
				write(write_pipe_fd,"seek -5\n",strlen("seek -5\n"));//快退。
				printf("ts_x = %d, ts_y = %d\r\n", ts_x, ts_y);

			}
			//发送命令回到主界面
			else if((ts_y > 0 && ts_y < 100) && (ts_x > 700 && ts_x < 800))
			{
				char temp2[30]; 
				char command2[30];
				int pid = getpid();
				sprintf(temp2, "%d", pid);
				sprintf(command2, "kill -9 %s", temp2);

				int fd = open("/tmp/musicpipe", O_RDWR);
				char send_buf[100] = "cd /mnt/udisk && ./mainWindowApp";
				write(fd, send_buf, sizeof(send_buf));
				printf("send message\r\n");
				system(command2);
			}
	
			else if((ts_y > 400 && ts_y < 450) && (ts_x > 300 && ts_x < 360))
			{
				write(write_pipe_fd,"seek +5\n",strlen("seek -5\n"));//快进。
				printf("ts_x = %d, ts_y = %d\r\n", ts_x, ts_y);
			}

			else if((ts_y > 400 && ts_y < 450) && (ts_x > 200 && ts_x < 230))
			{
				
				printf("ts_x = %d, ts_y = %d\r\n", ts_x, ts_y);
				if(play_pause_flag == 0){
					write(write_pipe_fd,"pause\n",strlen("pause\n"));
					play_pause_flag = 1;
				}
				else if(play_pause_flag == 1){
					write(write_pipe_fd,"pause\n",strlen("pause\n"));
					play_pause_flag = 0;
				}
				pthread_mutex_lock(&screen_mutex);
				screen_change = 1;
				pthread_mutex_unlock(&screen_mutex);
				pthread_cond_signal(&screen_cond);

			}
			else if ((ts_y > 395 && ts_y < 430) && (ts_x > 700 && ts_x < 750))
			{
				printf("ts_x = %d, ts_y = %d\r\n", ts_x, ts_y);
				if(mute_flag == 1){
					write(write_pipe_fd,"mute 1\n",strlen("mute 1\n"));
					mute_flag = 0;
				}
				else if(mute_flag == 0){
					write(write_pipe_fd,"mute 0\n",strlen("mute 0\n"));
					mute_flag = 1;
				}
		
			}
			else if ((ts_y > 395 && ts_y < 430) && ( ts_x > 420 && ts_x < 470))
			{
				
				printf("ts_x = %d, ts_y = %d\r\n", ts_x, ts_y);
				if(like_flag == 1){
					//lcd_show_bmp("play_like.bmp", 0, 0);
					like_flag = 0;
				}
				else {
					//lcd_show_bmp("play_unlike.bmp", 0, 0);
					like_flag = 1;
				}
				pthread_mutex_lock(&screen_mutex);
				screen_change = 1;
				pthread_mutex_unlock(&screen_mutex);
				pthread_cond_signal(&screen_cond);
			}
	
			else if((ts_y > 395 && ts_y < 430) && ( ts_x > 520 && ts_x < 570))
			{	
				play_pause_flag = 1;
				printf("ts_x = %d, ts_y = %d\r\n", ts_x, ts_y);
				char switch_buf[100];
				if(current_song == 0){
					write(write_pipe_fd, "volume 10 1\n", strlen("volume 10 1\n"));
					sprintf(switch_buf, "loadfile /mnt/udisk/music/audio/%s &", audio_name[current_song]);
					write(write_pipe_fd, switch_buf, strlen(switch_buf));
					write(write_pipe_fd, "volume 10 1\n", strlen("volume 10 1\n"));
					current_song = 1;
				}
				else{
					write(write_pipe_fd, "volume 10 1\n", strlen("volume 10 1\n"));
					sprintf(switch_buf, "loadfile /mnt/udisk/music/audio/%s &", audio_name[current_song]);
					write(write_pipe_fd, switch_buf, strlen(switch_buf));
					write(write_pipe_fd, "volume 10 1\n", strlen("volume 10 1\n"));
					current_song = 0;
				}
				pthread_mutex_lock(&screen_mutex);
				screen_change = 1;
				pthread_mutex_unlock(&screen_mutex);
				pthread_cond_signal(&screen_cond);
			}
			else
			{
				flag_x_y = 0;
				break;
			}
			flag_x_y = 0;
		}
		//pthread_mutex_unlock(&music_mutex);
	}
}

void *music_slider_func(void *arg)
{
	printf("enter music_slider_func\r\n");
	while(1){
		while(up_down_slide_flag == 1){
			if(slider_up == 1){
				slider_up = 0;
				write(write_pipe_fd,"volume +3\n",strlen("volume +3\n"));//加声音
				printf("volume++\r\n");
				//up_down_slide_flag == 0;
			}
			else if(slider_down == 1){
				write(write_pipe_fd,"volume -3\n",strlen("volume +3\n"));//加声音
				slider_down = 0;
				//up_down_slide_flag == 0;
				printf("volume--\r\n");
			}
			up_down_slide_flag == 0;
		}
	}
}

void *music_screen_switch_func(void *arg)
{
	while(1){
		pthread_mutex_lock(&screen_mutex);
		while(screen_change == 0)
			pthread_cond_wait(&screen_cond, &screen_mutex);
		while(screen_change == 1){
			if(like_flag == 1 && play_pause_flag == 1){
				lcd_show_bmp("play_like.bmp", 0, 0);
			}
			else if(like_flag == 1 && play_pause_flag == 0){
				lcd_show_bmp("stop_like.bmp", 0, 0);
			}
			else if(like_flag == 0 && play_pause_flag == 1){
				lcd_show_bmp("play_unlike.bmp", 0, 0);
			}
			else if(like_flag == 0 && play_pause_flag == 0){
				lcd_show_bmp("stop_unlike.bmp", 0, 0);
			}
			screen_change = 0;
		}
		pthread_mutex_unlock(&screen_mutex);
	}
}


pthread_t back_pid;
void *back(void *arg)
{
	printf("enter back thread\r\n");
	char rec_buf[100];
	int fd = open("/tmp/musicpipe", O_RDWR);
	read(fd, rec_buf, sizeof(rec_buf));
	printf("receive message\r\n");
	printf("rec_buf = %s\r\n", rec_buf);
	system(rec_buf);
}

int main(int argc, char *argv[])
{

	int ret = 0;
	int i = 0;
	ret = mkfifo("/tmp/musicpipe", 0777);
	if(ret < 0){
		perror("!!mkfifo!!");
	}

	audio_dir = opendir("/mnt/udisk/music/audio");
	if(audio_dir == NULL){
		perror("open audio dir error");
	}

	while((audio_dirent = readdir(audio_dir)) != NULL){
		if(strlen(audio_dirent->d_name) <= 2){
			continue;
		}
		else{
			audio_name[i] = audio_dirent->d_name;
			i++;
		}
	}
	
	lcd_show_bmp("play_unlike.bmp", 0, 0);
	if(fork() == 0){
				pthread_create(&back_pid, NULL, back, NULL);
				char command_buf[100];
				printf("enter child process\r\n");
				sprintf(command_buf, "mplayer -idle -quiet -input file=/tmp/musicpipe /mnt/udisk/music/audio/%s &", audio_name[0]);
				system(command_buf);		
				while(1){
				}
		
	}
	else{
		pthread_create(&music_slide_tid, NULL, music_slider_func, NULL);
		pthread_create(&music_area_switch_tid, NULL, music_area_switch, NULL);
		pthread_create(&music_screen_switch_tid, NULL, music_screen_switch_func, NULL);
		
		pthread_mutex_init(&music_mutex, NULL);
		pthread_cond_init(&music_cond, NULL);

		pthread_mutex_init(&screen_mutex, NULL);
		pthread_cond_init(&screen_cond, NULL);
		
		pthread_mutex_init(&slide_mutex, NULL);
		pthread_cond_init(&slide_cond, NULL);

		printf("enter parent process\r\n");
		write_pipe_fd = open("/tmp/musicpipe", O_WRONLY);
		write(write_pipe_fd, "volume 10 1\n", strlen("volume 10 1\n"));
		while(1){
			music_get_touch();
		}
	}

	exit(0);	
	
}

